/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Web.Configuration;
using System.Web.Security;
using DaveSexton.DocProject.Wizards.Foundation;

namespace DaveSexton.DocProject.Wizards
{
	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
	public sealed class CreateDocSiteCredentialsStep : WizardStep
	{
		#region Public Properties
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1802:UseLiteralsWhereAppropriate")]
		public static readonly string AdminUserReplacementToken = "$admin$";

		public override string Name
		{
			get
			{
				return WizardText.CreateDocSiteCredentialsStepName;
			}
		}

		public override bool CanPreloadUserInterface
		{
			get
			{
				return true;
			}
		}

		public override bool Visible
		{
			get
			{
				return configUser != null;
			}
		}
		#endregion

		#region Private / Protected
		private CreateDocSiteCredentialsControl control;
		private readonly System.Configuration.Configuration config;
		private readonly FormsAuthenticationUser configUser;
		private readonly FormsAuthPasswordFormat format;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="CreateDocSiteCredentialsStep" /> class.
		/// </summary>
		public CreateDocSiteCredentialsStep(IDocProject project)
		{
			if (project == null)
				throw new ArgumentNullException("project");

			if (project.IsDocSite)
			{
				string webConfigFile = System.IO.Path.Combine(project.Directory, "web.config");

				ExeConfigurationFileMap map = new ExeConfigurationFileMap();
				map.ExeConfigFilename = webConfigFile;

				// NOTE: if the file doesn't exist then config will still be assigned to an instance but the HasFile property 
				// will return false (this is verified below).
				try
				{
					config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
				}
				catch (ConfigurationErrorsException ex)
				{
					Log.Exception(ex, Resources.Text.CannotOpenWebConfigLogMessage, webConfigFile);
				}

				if (config != null && config.HasFile)
				{
					AuthenticationSection auth = config.GetSection("system.web/authentication") as AuthenticationSection;

					if (auth != null)
					{
						// NOTE: in testing, an empty collection of users is returned even if no forms and/or credentials section appears in the web.config file.
						foreach (FormsAuthenticationUser user in auth.Forms.Credentials.Users)
						{
							if (AdminUserReplacementToken.Equals(user.Name, StringComparison.OrdinalIgnoreCase))
							{
								format = auth.Forms.Credentials.PasswordFormat;
								configUser = user;
								break;
							}
						}
					}
				}
			}
		}
		#endregion

		#region Methods
		protected override object GetUserInterface(WizardController controller, bool preloading)
		{
			if (control == null)
			{
				control = new CreateDocSiteCredentialsControl();
				control.Format = format;
			}

			return control;
		}

		protected override bool CanNavigateAway(WizardController controller, WizardStep toStep, bool forward)
		{
			return !forward || (control != null && control.Validate());
		}

		protected override void WizardFinished(WizardController controller)
		{
			configUser.Name = control.UserName;

			if (format == FormsAuthPasswordFormat.Clear)
				configUser.Password = control.Password;
			else
				configUser.Password = FormsAuthentication.HashPasswordForStoringInConfigFile(control.Password, format.ToString());

			config.Save(ConfigurationSaveMode.Modified);
		}

		protected override void WizardCanceled(WizardController controller)
		{
			// do nothing
		}
		#endregion		
	}
}
